package yf.platform.biz;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.yfsoft.comm.util.StringUtil;
import org.yfsoft.comm.util.TimeUtil;

import yf.platform.bo.BizResult;
import yf.platform.bo.JsonBizResult;
import yf.platform.ctl.GlobalKey;
import yf.platform.dao.DaoSupport;
import yf.platform.dao.JfinalDaoSupport;


public abstract class Service {

	protected Service (){}
	
	protected HttpServletRequest request = null;
	
	protected HttpServletResponse response = null;
	
	protected DaoSupport daoSupport = null;

	public void setDaoSupport(DaoSupport daoSupport){
		this.daoSupport = daoSupport;
	}

	private Map<String,String> input = null;
	
	protected BizResult rst = null;
	
	protected boolean isajax = false;

	private static final String PACKAGE_NAME = "yf.platform.biz";

	private static final Map<String,Service> services = new HashMap<String, Service>();

	private static final DaoSupport sDaoSupport = new JfinalDaoSupport();

	public static Service build(String s){
		if(services.containsKey(s)){
			return services.get(s);
		}
		String firstChar = s.substring(0,1);
		try {
			Class cls = Class.forName(PACKAGE_NAME + "." + s.replaceFirst(firstChar,firstChar.toUpperCase()) + "Service");
			Service service = (Service)cls.newInstance();
			service.setDaoSupport(sDaoSupport);
			services.put(s , service);
			return service;
		} catch (ClassNotFoundException e) {
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected final void reflect(String o){
		try{
			Class cls = this.getClass();
			Method m = cls.getMethod(o, Map.class);
			try{
				rst.setCode(-1);
				forward((BizResult)m.invoke(this, this.input));
			}catch(Exception hex){
				System.out.println(hex.toString());
				throw hex;
			}
		}catch(Exception e){
			
		}
	}
	
	public final void execute(Map<String,String> input,HttpServletRequest request, HttpServletResponse response){
		this.request = request;
		this.response = response;
		this.input = input;
		String o = input.get("o");
		String s = input.get("s");
		input.remove("o");
		input.remove("s");
		isajax = input.containsKey("isajax")?("1".equals(input.get("isajax"))):false;
		rst = new JsonBizResult(request,-99,BizResult.ECHO,"");
		if(!StringUtil.isNullOrEmpty(o)){
			//session失效
			if(!"common".equals(s)){
				if(request.getSession().getAttribute(GlobalKey.USER)==null){
					try {
						response.sendRedirect("WIDGETS/login.jsp");
					} catch (IOException e) {}
					return;
				}
				if(!"install".equals(o)){
					String ip = getRemoteAddress(request);
					//记录用户的操作日志
					Map<String,String> actionLog = new HashMap<String,String>();
					actionLog.put("l_time", TimeUtil.getNow());
					actionLog.put("l_ip", ip);
					actionLog.put("l_operate", o);
					Map<String,Object> user = rst.getSissAttribute(GlobalKey.USER);
					if(user == null){
						actionLog.put("l_user", "login");
					}else{
						actionLog.put("l_user", user.get("ui_nickname").toString());
					}
					actionLog.put("l_service", s);
					actionLog.put("l_input", input.toString());
					try{
						daoSupport.insert("sys_log", actionLog);
					}catch(Exception e){
						
					}
				}
			}
			
			reflect(o);
		}
		
		//TODO....
	}
	
	protected final void forward(BizResult rst) throws Exception{
		//如果业务请求是通过ajax来的，则直接输出业务结果
		if(isajax){
			response.setContentType("text/json;charset=UTF-8");
			response.getWriter().print(this.rst.toString());
			return;
		}
		//业务处理错误，直接输出错误信息
		if(0 != rst.getCode()){response.getWriter().print(rst.getMsg()); return;}
		byte t = rst.getType();
		switch(t){
		case BizResult.JUMP:
			//处理跳转
			response.sendRedirect(rst.getPage());
			return;
		case BizResult.REDIRECT:
			//请求转发
			request.getRequestDispatcher(rst.getPage()).forward(request, response);
			return;	
		}
		//直接输出处理内容
		response.getWriter().print(rst.getData());
		response.flushBuffer();
	}
	
	protected final String getRemoteAddress(HttpServletRequest request) {  
        String ip = request.getHeader("x-forwarded-for");  
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
            ip = request.getHeader("Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
            ip = request.getHeader("WL-Proxy-Client-IP");  
        }  
        if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
            ip = request.getRemoteAddr();  
        }  
        return ip;  
    } 
}
